package org.libarae.communication;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.libarae.communication.common.Type;
import org.libarae.communication.request.AccountInfoRequest;
import org.libarae.communication.request.AccountUpdateRequest;
import org.libarae.communication.request.AdminActionRequest;
import org.libarae.communication.request.AdminPanelRequest;
import org.libarae.communication.request.BookInfoRequest;
import org.libarae.communication.request.BookSearchRequest;
import org.libarae.communication.request.ChangeMessageStatusRequest;
import org.libarae.communication.request.CreateBookRequest;
import org.libarae.communication.request.EditBookRequest;
import org.libarae.communication.request.FeaturedTabRequest;
import org.libarae.communication.request.GetThreadMessagesRequest;
import org.libarae.communication.request.HeartBeatRequest;
import org.libarae.communication.request.IsbnLookUpRequest;
import org.libarae.communication.request.LoginRequest;
import org.libarae.communication.request.LogoutRequest;
import org.libarae.communication.request.MailboxMessagesRequest;
import org.libarae.communication.request.ModeratorActionRequest;
import org.libarae.communication.request.ModeratorPanelRequest;
import org.libarae.communication.request.NewUserRequest;
import org.libarae.communication.request.PictureRequest;
import org.libarae.communication.request.ProfileTabRequest;
import org.libarae.communication.request.Request;
import org.libarae.communication.request.SendMessageRequest;
import org.libarae.communication.request.ServerInfoRequest;
import org.libarae.communication.request.ServerPingRequest;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class RequestXmlHandler {
	/*
	 *  Parses a message from the string formated in the proper XML
	 *  
	 *  Takes the String that is the the xml
	 *  Returns the proper Request object with all of the information filled in	 * 
	 */
	public static Request parseXML(String message) throws SAXException, IOException, ParserConfigurationException, XmlParseException{
		//Set up the XML decoder	
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(new ByteArrayInputStream(message.getBytes()));
		doc.getDocumentElement().normalize();
		
		//get the type of the xml object
		int type;
		try{
			type = Integer.parseInt(doc.getDocumentElement().getAttribute("typeID"));
		}
		catch(NumberFormatException e){
			throw new XmlParseException("Could not parse numeric type from "+doc.getDocumentElement().getNodeName(),e);
		}
		
		//Switch on the type to make the proper object
		Request obj;
		switch(type){
			case Type.BOOK_INFO:
				obj = new BookInfoRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.BOOK_SEARCH:
				obj = new BookSearchRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.CREATE_BOOK:
				obj = new CreateBookRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.FEATRUED_TAB:
				obj = new FeaturedTabRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.HEART_BEAT:
				obj = new HeartBeatRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.ISBN_LOOKUP:
				obj = new IsbnLookUpRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.LOGIN:
				obj = new LoginRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.MAILBOX_MESSAGES:
				obj = new MailboxMessagesRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.NEW_USER:
				obj = new NewUserRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.PROFILE_TAB:
				obj = new ProfileTabRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.SEND_MESSAGE:
				obj = new SendMessageRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.LOGOUT:
				obj = new LogoutRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.SERVER_PING:
				obj = new ServerPingRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.ACCOUNT_INFO:
				obj = new AccountInfoRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.ACCOUNT_UPDATE:
				obj = new AccountUpdateRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.MODERATOR_PANEL:
				obj = new ModeratorPanelRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.MODERATOR_ACTION:
				obj = new ModeratorActionRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.ADMIN_PANEL:
				obj = new AdminPanelRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.ADMIN_ACTION:
				obj = new AdminActionRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.SERVER_INFO:
				obj = new ServerInfoRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.CHANGE_MESSAGE_STATUS:
				obj = new ChangeMessageStatusRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.PICTURE:
				obj = new PictureRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.GET_THREAD_MESSAGES:
				obj = new GetThreadMessagesRequest();
				obj.decodeXML(doc);
				return obj;
			case Type.EDIT_BOOK:
				obj = new EditBookRequest();
				obj.decodeXML(doc);
				return obj;
			default:
				throw new XmlParseException("Message Object Type ID not Reconginzed.");
		}			
	}
	
	/*
	 *  Creates the XML dumped to a String from the request object given.
	 *  
	 *  returns the String of xml 
	 */
	public static String createXML(Request object) throws XmlParseException{
		return object.createXML();
	}	
}
